package com.joey.cloud.flowable.service;

import com.joey.cloud.flowable.dto.TaskEventMsgDto;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class FlowProcessService {
    //操作流程定义相关  删除 部署流程定义等
    @Autowired
    RepositoryService repositoryService;
    //操作流程实例的
    @Autowired
    RuntimeService runtimeService;
    //操作任务相关的
    @Autowired
    TaskService taskService;
    //查询历史表数据的
    @Resource
    HistoryService historyService;
    //操作用户或者组织机构相关的
    @Resource
    IdentityService identityService;
    //流程引擎类
    @Resource
    ProcessEngine processEngine;



    /**
     * 判断流程实例是否结束
     * @param processInstanceId
     * @return
     */
    public boolean isFinished(String processInstanceId) {
        return historyService.createHistoricProcessInstanceQuery().finished()
                .processInstanceId(processInstanceId).count() > 0;
    }
    /**
     * 获取流程实例流程图
     * @param processInstanceId
     * @return
     */
    public InputStream getDiagramByProcessId(String processInstanceId){
        String processDefinitionId = "";
        if (this.isFinished(processInstanceId)) {
            // 如果流程已经结束，则得到结束节点
            HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            processDefinitionId=pi.getProcessDefinitionId();
        } else {
            // 如果流程没有结束，则取当前活动节点
            // 根据流程实例ID获得当前处于活动状态的ActivityId合集
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            processDefinitionId=pi.getProcessDefinitionId();
        }
        List<String> highLightedActivitis = new ArrayList<String>();
        /**
         * 获得活动的节点
         */
        List<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
        for(HistoricActivityInstance tempActivity : highLightedActivitList){
            String activityId = tempActivity.getActivityId();
            highLightedActivitis.add(activityId);
        }
        List<String> flows = new ArrayList<>();
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        //png
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis, flows, engconf.getActivityFontName(),
                engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
        return in;
    }

    /**
     * 获取流程定义流程图
     * @param processDefinitionId
     * @return
     */
    public InputStream getDiagramByDefinitionId(String processDefinitionId){
        List<String> highLightedActivitis = new ArrayList<String>();
        List<String> flows = new ArrayList<>();
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        //png
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis, flows, engconf.getActivityFontName(),
                engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
        return in;
    }

    /**
     * 通过流程实例id获取流程实例
     * @param processInstanceId
     * @return
     */
    public ProcessInstance getProcessInstanceById(String processInstanceId){
        return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
    }
    /**
     * 通过流程实例id获取流程实例
     * @param processDefinitionId
     * @return
     */
    public ProcessDefinition getProcessDefinitionById(String processDefinitionId){
        return repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
    }

    public ProcessDefinition getProcessDefinitionByTaskId(String taskId){
        String processDefinitionId = historyService.createHistoricTaskLogEntryBuilder().taskId(taskId).getProcessDefinitionId();
        return getProcessDefinitionById(processDefinitionId);
    }


    public void sendEventMsg(String eventType,String taskId, String processInstanceId, String currentStep) {
        ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();;
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionId(process.getProcessDefinitionId()).singleResult();
        //发送消息
        TaskEventMsgDto dto = new TaskEventMsgDto();
        dto.setTaskId(taskId);
        dto.setProcessInstanceId(process.getProcessInstanceId());
        dto.setProcessDefinitionId(process.getProcessDefinitionId());
        dto.setBusinessKey(process.getBusinessKey());
        dto.setCurrentStep(currentStep);
        dto.setEventType(eventType);
        dto.setSolKey(definition.getKey());
        dto.setParam(process.getProcessVariables());
        log.info("触发流程事件监听",dto);
        System.out.println("触发流程事件监听，类型="+dto.getEventType());
        //TODO 发送MQ消息消费事件

    }
}
